#pragma once

namespace IcyCrystal {
	
	class Type;
	class Symbol;
	class SyntaxTree;
	struct dagCompare;

	typedef vector<SyntaxTree*> SyntaxTreeList;
	typedef vector<Symbol*> SymbolList;
	typedef map<SyntaxTree*, SyntaxTree*, dagCompare> DagMap;
	

	enum NodeType {
		NODE_ASSIGN, NODE_INITIALIZE, NODE_EXPRESSION, NODE_TOKEN,
		NODE_SYMBOL, NODE_ARRAY_ACCESS,
		NODE_BLOCK_END, NODE_RETURN,
		NODE_EOF
	};
	enum NodeFlags {
		NODE_IS_ARRAY_ACCESS,
		NODE_IS_ARRAY_INITIATOR,
		NO_FLAGS
	};

	class SyntaxTree {
	public:
		SyntaxTree();

		NodeType nodeType;
		NodeFlags nodeFlags;
		

		union {
			Token nodeToken;
			Symbol* sym;
		} inner;

		ArrayNumElements accessType;
		union {
			SyntaxTree* arrayAccess;
			int constArrayAccess;
			SyntaxTreeList* arrayInitArguments;
		} extra;

		Type* expressionReturnType;

		SyntaxTree* left;
		SyntaxTree* right;

		/** The size in bytes of whatever this node is representing */
		unsigned int getReturnSize();

	};

}
